# -*- coding: utf-8 -*-

import unittest
import os
import codecs
import json
import urllib2
from json_loader import JsonLoader
from model.gamestate import *
from constants import PATH
from mox import *
import json


class JsonLoaderTest(unittest.TestCase):
    def setUp(self):
        self.mox = Mox()
        self.json_loader = JsonLoader()
        self.json_string = []
        self.example_cnt = 2
        for example_num in range(self.example_cnt):
            with codecs.open(os.path.join('test_data', 'example_'
                                          + str(example_num) + '.json'),
                             encoding='utf-8', mode='r') as f:
                self.json_string.append(f.read())

    def test_json_translate(self):
        for example_num in range(self.example_cnt):
            self.game_state = self.json_loader.json_translate(json.loads(
                self.json_string[example_num]))

            self.assertTrue(isinstance(self.game_state, GameState))
            self.assertTrue(isinstance(self.game_state.players, Players))
            self.assertTrue(isinstance(self.game_state.hat, Hat))
            self.assertTrue(isinstance(self.game_state.settings, Settings))

            for player in self.game_state.players.players:
                self.assertTrue(isinstance(player, Player))
                self.assertTrue(isinstance(player.name, unicode))
                self.assertTrue(isinstance(player.words, list))

            for word in self.game_state.hat.words:
                self.assertTrue(isinstance(word, Word))
                self.assertTrue(isinstance(word.text, unicode))
                self.assertTrue(isinstance(word.owner, Player) or
                                isinstance(word.owner, type(None)))

            self.assertTrue(isinstance(self.game_state.settings.
                                       time_per_round_sec, int))
            self.assertTrue(isinstance(self.game_state.settings.
                                       time_before_out_sec, int))
            self.assertTrue(isinstance(self.game_state.settings.
                                       skip_words, int))

    def test_load_from_url(self):
        url = 'test string'
        with codecs.open(PATH + '/test_data/example_0.json',
                         encoding='utf-8', mode='r') as file_opened:
            self.mox.StubOutWithMock(urllib2, 'urlopen')
            urllib2.urlopen(IsA(str), timeout=IsA(int)).AndReturn(file_opened)
            self.mox.ReplayAll()
            self.json_string = self.json_loader.load_from_url(url)

        self.mox.UnsetStubs()
        self.mox.VerifyAll()

        with codecs.open(PATH + '/test_data/example_0.json',
                         encoding='utf-8', mode='r') as file_opened:
            self.assertEqual(self.json_string, json.loads(file_opened.read()))

    def test_load_game_from_url(self):
        url = 'test string'
        with codecs.open(PATH + '/test_data/example_0.json',
                         encoding='utf-8', mode='r') as file_opened:
            self.mox.StubOutWithMock(urllib2, 'urlopen')
            urllib2.urlopen(IsA(str), timeout=IsA(int)).AndReturn(file_opened)
            self.mox.ReplayAll()
            self.game_state = self.json_loader.load_game_from_url(url)

        self.mox.UnsetStubs()
        self.mox.VerifyAll()
        self.assertTrue(isinstance(self.game_state, GameState))

    def test_dump_to_url(self):
        url = 'test string'
        with codecs.open(PATH + '/test_data/example_0.json',
                         encoding='utf-8', mode='r') as file_opened:
            self.mox.StubOutWithMock(urllib2, 'urlopen')
            urllib2.urlopen(IsA(str), IsA(str), timeout=IsA(int))
            self.mox.ReplayAll()
            self.json_loader.dump_to_url(url, self.json_string[0])

        self.mox.UnsetStubs()
        self.mox.VerifyAll()

if __name__ == "__main__":
    unittest.main()
